package com.zg.ktcomwan.fragment

import android.app.ProgressDialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.paging.LoadState
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.zg.core.ext.logI
import com.zg.ktcomwan.R
import com.zg.ktcomwan.databinding.ErrorLayoutBinding
import com.zg.ktcomwan.databinding.FragmentArticleBinding
import com.zg.ktcomwan.ext.toast
import com.zg.ktcomwan.vm.AbsViewModel
import kotlinx.android.synthetic.main.fragment_article.*
import kotlinx.android.synthetic.main.fragment_article.rv
import kotlinx.android.synthetic.main.fragment_article.srl
import kotlinx.android.synthetic.main.fragment_per_project.*
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import java.lang.reflect.ParameterizedType

/***
 * @Author:      zxd
 * @CreateDate:  2021/8/16 10:14
 * @Description: 基础的list的碎片
 */
abstract class AbsListFragment<T : Any, M : AbsViewModel<T>> : Fragment() {

    lateinit var binding: FragmentArticleBinding
    lateinit var model: M
    lateinit var mAdapter: PagingDataAdapter<T, out RecyclerView.ViewHolder>

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentArticleBinding.inflate(inflater, container, false)
        mAdapter = getAdapter()
        binding.rv.adapter = mAdapter
        binding.rv.layoutManager = LinearLayoutManager(activity)



        binding.srl.setEnableRefresh(true)
        binding.srl.setEnableLoadMore(true)

        genericViewModel()

        lifecycleScope.launch {
            model.articleList.collectLatest {
                mAdapter!!.submitData(it)
            }
        }

        binding.srl.setEnableRefresh(true)
        binding.srl.setOnRefreshListener {
            mAdapter!!.notifyDataSetChanged()
            srl.finishRefresh(true)
        }

        addState(mAdapter)

        return binding.root
    }

    abstract fun getAdapter(): PagingDataAdapter<T, out RecyclerView.ViewHolder>

    fun genericViewModel() {
        //利用 子类传递的 泛型参数实例化出absViewModel 对象。
        val type =
            javaClass.genericSuperclass as ParameterizedType
        val arguments = type.actualTypeArguments
        if (arguments.size > 1) {
            val argument = arguments[1]
            val modelClaz: Class<*> = (argument as Class<*>).asSubclass(
                AbsViewModel::class.java
            )
            model = ViewModelProvider(this)
                .get<ViewModel>(modelClaz as Class<ViewModel>) as M
        }
    }

    fun addState(adapter: PagingDataAdapter<T, out RecyclerView.ViewHolder>) {
        //打开界面，加载数据的时候显示loading，如果出数据了，那么隐藏掉对话框
        val dialog = ProgressDialog(activity)
        dialog.setTitle("Loading......")
        dialog.setMessage("等待中...")
        dialog.isIndeterminate = true
        dialog.setCancelable(false)
        adapter!!.addLoadStateListener {
            when (it.source.refresh) {
                //数据加载中。
                is LoadState.Loading -> {
                    dialog.show()
                    logI("Loading: ---------------------")
                }
                //内存中有已经获取的数据，即使往下滑，Paging 也不需要请求更多的数据。
                is LoadState.NotLoading -> {
                    dialog.cancel()
                    logI("NotLoading: +++++++++++++++")
                }
                //请求数据时返回了一个错误。
                is LoadState.Error -> {
                    dialog.cancel()
                    logI("Error: ======================")
                    toast("出现错误")
                    val errorLayoutBinding = DataBindingUtil.inflate<ErrorLayoutBinding>(
                        layoutInflater,
                        R.layout.error_layout,
                        rv.rootView as ViewGroup?,
                        true
                    )
                    errorLayoutBinding.retryBtn.setOnClickListener {
                        (rv.rootView as ViewGroup?)?.removeView(errorLayoutBinding.root)
                        adapter.refresh()
                    }
                }
            }
        }

        /***
         * LoadStateAdapter：可以添加页头/页脚，方便实现loadmore的样式
         * fun withLoadStateHeader(header: LoadStateAdapter<*> ) 头部添加状态适配器
         * fun withLoadStateFooter(footer: LoadStateAdapter<*> ) 底部添加状态适配器
         * fun withLoadStateHeaderAndFooter(header: LoadStateAdapter<>, footer: LoadStateAdapter<> ) 头尾都添加状态适配器
         * 谷歌出过一个 MergeAdapter，就是把多个RecyclerView.Adapter 合并成一个
         */
//        rv.adapter = adapter.withLoadStateHeaderAndFooter(
//            TestLoadStateAdapter(adapter),
//            HeaderLoadStateAdapter(adapter)
//        )
        //rv.adapter = adapter.withLoadStateHeader(ArticleHeaderLoadStateAdapter())
    }
}